package helper

import (
	"math/rand"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
	"github.com/pkg/errors"
)

const (
	issuer = "www.yefei.com"
	expire = 10 * time.Hour
	key    = "yefei1210"
)

func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method

		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
		c.Header("Access-Control-Allow-Credentials", "true")

		//放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}
		// 处理请求
		c.Next()
	}
}

// TokenAuthMiddleware check token
func TokenAuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		//if c.ClientIP() == "127.0.0.1" || c.ClientIP() == "::1" {
		//	c.Next()
		//	return
		//}
		token := c.GetHeader("token")
		if token == "" {
			SetHttpMsgResp(c, HttpCodeInternalFail, "token is nil")
			c.Abort()
			return
		}
		t, err := ParseToken(token)
		if err != nil {
			SetHttpMsgResp(c, HttpCodeInternalFail, err.Error())
			// common.Response(c, err, common.TokenInvalidErr, nil)
			c.Abort()
			return
		}
		c.Request.Header.Set("id", t)
		c.Next()
	}
}

// GenerateToken 生成jwt signed token
func GenerateToken(id string) string {
	//jwfConf := config.JWTInfo()
	claim := jwt.RegisteredClaims{
		//Audience:
		//ExpiresAt: time.Now().Add(expire).Unix(),
		ID:     id,
		Issuer: issuer,
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claim)
	ss, err := token.SignedString([]byte(key))
	if err != nil {
		panic(err)
	}
	return ss
}

//ParseToken parse jwt token
func ParseToken(ss string) (string, error) {
	claims := jwt.RegisteredClaims{}
	token, err := jwt.ParseWithClaims(ss, &claims, func(token *jwt.Token) (interface{}, error) {
		return []byte(key), nil
	})
	if err != nil {
		return "", err
	}
	if !token.Valid {
		return "", errors.New("invalid token")
	}
	return claims.ID, nil
}

// GetRandomString 随机字符串
func GetRandomString(n int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyz"
	bytes := []byte(str)
	var result []byte
	rand.Seed(time.Now().Unix())
	for i := 0; i < n; i++ {
		result = append(result, bytes[rand.Intn(len(bytes))])
	}
	return string(result)
}

func GetRandomNumberString(n int) string {
	bytes := []byte("0123456789")
	var result []byte
	rand.Seed(time.Now().Unix())
	for i := 0; i < n; i++ {
		result = append(result, bytes[rand.Intn(len(bytes))])
	}
	return string(result)
}
